#include <Arduino.h>
#include <SPI.h>
#include <TFT_eSPI.h>
#include "ai_detection.h"
#include "modbus.h"

// 函数声明
void modbusUpdateInputRegisters(float* sensorValues);

// 定义引脚
const int RELAY_PINS[4] = {2, 3, 4, 5};
const int SENSOR_PINS[4] = {A0, A1, A2, A3};

// 初始化HMI
TFT_eSPI tft = TFT_eSPI();

// 初始化AI检测器
AIFaultDetector aiDetector;

// 串口通信参数
const long BAUD_RATE = 9600;

// 传感器校准参数
float sensorCalib[4] = {1.0, 1.0, 1.0, 1.0};
float sensorOffset[4] = {0.0, 0.0, 0.0, 0.0};

// 继电器状态
bool relayStates[4] = {false, false, false, false};

// 定时发送数据的间隔（毫秒）
const unsigned long DATA_SEND_INTERVAL = 500;
unsigned long lastSendTime = 0;

void setup() {
  // 初始化串口通信
  Serial.begin(BAUD_RATE);
  
  // 初始化继电器引脚为输出
  for (int i = 0; i < 4; i++) {
    pinMode(RELAY_PINS[i], OUTPUT);
    digitalWrite(RELAY_PINS[i], LOW);
  }
  
  // 初始化HMI
  tft.init();
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE);
  tft.setTextSize(2);
  tft.setCursor(10, 10);
  tft.println("迷你PLC系统就绪");
  
  // 初始化Modbus
  modbusInit(9600);
  
  // 初始化AI检测器的基线
  float baseline[4] = {0.2, 0.3, 0.1, 0.4};
  aiDetector.setBaseline(baseline);
  
  // 发送系统初始化完成消息
  sendSystemStatus("INIT_COMPLETE");
}

void loop() {
  // 读取传感器值并校准
  float sensorValues[4];
  for (int i = 0; i < 4; i++) {
    float rawValue = analogRead(SENSOR_PINS[i]) / 1023.0;
    sensorValues[i] = (rawValue * sensorCalib[i]) + sensorOffset[i];
  }
  
  // AI故障检测
  int faultIndex = aiDetector.detectFault(sensorValues);
  if (faultIndex >= 0) {
    // 触发故障保护
    for (int i = 0; i < 4; i++) {
      digitalWrite(RELAY_PINS[i], LOW);
      relayStates[i] = false;
    }
    tft.fillRect(10, 50, 220, 30, TFT_RED);
    tft.setCursor(10, 50);
    tft.println("故障检测: 通道" + String(faultIndex+1));
    
    // 发送故障警报
    char faultMsg[50];
    sprintf(faultMsg, "FAULT,CH%d", faultIndex+1);
    sendSystemStatus(faultMsg);
  } else {
    // 正常状态显示
    tft.fillRect(10, 50, 220, 30, TFT_BLACK);
    tft.setCursor(10, 50);
    tft.println("系统正常运行中");
  }
  
  // 定时发送传感器数据到Python服务
  unsigned long currentTime = millis();
  if (currentTime - lastSendTime >= DATA_SEND_INTERVAL) {
    sendSensorData(sensorValues);
    // 同时更新Modbus输入寄存器
    modbusUpdateInputRegisters(sensorValues);
    lastSendTime = currentTime;
  }
  
  // 处理从Python服务接收的命令
  processSerialCommands();
  
  // 处理Modbus请求
  modbusProcess();
  
  delay(50); // 稍微减少延迟，提高响应速度
}

// 发送传感器数据到Python服务
void sendSensorData(float sensorValues[]) {
  // 格式化数据: DATA,S1,S2,S3,S4,R1,R2,R3,R4
  Serial.print("DATA");
  for (int i = 0; i < 4; i++) {
    Serial.print(",");
    Serial.print(sensorValues[i], 4); // 保留4位小数
  }
  for (int i = 0; i < 4; i++) {
    Serial.print(",");
    Serial.print(relayStates[i] ? 1 : 0);
  }
  Serial.println();
}

// 发送系统状态消息
void sendSystemStatus(const char* statusMsg) {
  Serial.print("STATUS,");
  Serial.println(statusMsg);
}

// 处理从Python服务接收的命令
void processSerialCommands() {
  if (Serial.available() > 0) {
    String command = Serial.readStringUntil('\n');
    command.trim();
    
    // 解析命令
    if (command.startsWith("RELAY")) {
      // 格式: RELAY,通道号(1-4),状态(0-1)
      int comma1 = command.indexOf(',');
      int comma2 = command.indexOf(',', comma1 + 1);
      
      if (comma1 != -1 && comma2 != -1) {
        int channel = command.substring(comma1 + 1, comma2).toInt() - 1;
        int state = command.substring(comma2 + 1).toInt();
        
        if (channel >= 0 && channel < 4) {
          digitalWrite(RELAY_PINS[channel], state);
          relayStates[channel] = (state == 1);
          
          // 显示继电器状态
          char stateStr[50];
          sprintf(stateStr, "继电器%d:%s", channel+1, state ? "开启" : "关闭");
          tft.fillRect(10, 90, 220, 30, TFT_BLACK);
          tft.setCursor(10, 90);
          tft.println(stateStr);
          
          // 确认命令执行
          sendSystemStatus("CMD_EXECUTED");
        }
      }
    }
    else if (command.startsWith("CALIB")) {
      // 格式: CALIB,通道号(1-4),校准系数,偏移量
      // 这里可以添加校准逻辑
      sendSystemStatus("CALIB_RECEIVED");
    }
    else if (command == "RESET") {
      // 重置系统
      for (int i = 0; i < 4; i++) {
        digitalWrite(RELAY_PINS[i], LOW);
        relayStates[i] = false;
      }
      aiDetector.reset();
      sendSystemStatus("SYSTEM_RESET");
    }
  }
}

// 读取单个传感器的原始值（用于调试）
float readSensorRaw(int channel) {
  if (channel >= 0 && channel < 4) {
    return analogRead(SENSOR_PINS[channel]) / 1023.0;
  }
  return 0.0;
}